Skip to content

Fix FormUrlEncodedMatcher (+ refactor values / matchers logic) - #1503

Merged
StefH merged 4 commits into
masterfrom
formurl_match
Aug 20, 2026
Merged

StefH merged 4 commits into
masterfrom
formurl_match

Conversation

@StefH

@StefH StefH commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@StefH StefH self-assigned this Aug 19, 2026
@StefH
StefH requested a lite review from Copilot August 19, 2026 05:55
@codecov

codecov Bot commented Aug 19, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 72.15190% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 30.48%. Comparing base (42353f0) to head (3d7dbc8).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
...Mock.Net.Minimal/Matchers/FormUrlEncodedMatcher.cs 72.97% 10 Missing ⚠️
src/WireMock.Net.Shared/Matchers/MatchScores.cs 68.00% 8 Missing ⚠️
...ck.Net.Minimal/RequestBuilders/Request.WithBody.cs 0.00% 2 Missing ⚠️
src/WireMock.Net.Shared/Util/QueryStringParser.cs 84.61% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1503      +/-   ##
==========================================
- Coverage   30.76%   30.48%   -0.29%     
==========================================
  Files         163      163              
  Lines       42251    42626     +375     
==========================================
- Hits        12999    12995       -4     
- Misses      28889    29270     +381     
+ Partials      363      361       -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@StefH

StefH commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator Author

@Bafyn This fix is a rather big retfactor...

Can you also take a look?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes and refactors form-url-encoded body matching by moving form/query parameter values from single strings to WireMockList<string> (to support multi-value keys) and by reworking matcher scoring logic accordingly.

Changes:

  • Refactor form-url-encoded parsing and models to represent multiple values per key via WireMockList<string>.
  • Rework FormUrlEncodedMatcher and parameter matching score calculations to better handle multi-value matching scenarios.
  • Update/extend unit tests to cover single vs multiple values and AND/OR operator behaviors.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
test/WireMock.Net.Tests/WireMockServerTests.WithBody.cs Adds a typed FormUrlEncoded body func test using WireMockList<string> values.
test/WireMock.Net.Tests/Util/QueryStringParserTests.cs Updates parser tests for WireMockList<string>-based outputs.
test/WireMock.Net.Tests/RequestMatchers/RequestMessageParamMatcherTests.cs Updates param matcher tests for new scoring behavior and newer collection literals.
test/WireMock.Net.Tests/RequestBuilders/RequestBuilderWithBodyTests.cs Updates request builder test to use WireMockList<string> form-url-encoded bodies.
test/WireMock.Net.Tests/Matchers/FormUrlEncodedMatcherTests.cs Major expansion of matcher tests across single/multiple values and AND/OR logic.
test/WireMock.Net.Tests/Abstractions/WireMockListTests.cs Adds equality/operator + Equals/GetHashCode tests for WireMockList<string>.
src/WireMock.Net.Shared/Util/QueryStringParser.cs Changes TryParse to collect multiple values per key into WireMockList<string>.
src/WireMock.Net.Shared/RequestBuilders/IBodyRequestBuilder.cs Breaks API type for form-url-encoded body func to use WireMockList<string>.
src/WireMock.Net.Shared/Models/BodyData.cs Updates BodyAsFormUrlEncoded to IDictionary<string, WireMockList<string>>.
src/WireMock.Net.Shared/Matchers/MatchScores.cs Broadens score helpers to IEnumerable<T> and adds list-vs-matchers scoring helper.
src/WireMock.Net.Shared/Extensions/AnyOfExtensions.cs Minor using cleanup.
src/WireMock.Net.Minimal/RequestBuilders/Request.WithBody.cs Updates WithBody overload signature for form-url-encoded func.
src/WireMock.Net.Minimal/Matchers/Request/RequestMessageParamMatcher.cs Switches param scoring to the new MatchScores.ToScore(list, matchers) logic.
src/WireMock.Net.Minimal/Matchers/Request/RequestMessageBodyMatcher.cs Updates form-url-encoded func signature to use WireMockList<string>.
src/WireMock.Net.Minimal/Matchers/FormUrlEncodedMatcher.cs Reworks internal representation and matching/scoring for multi-value inputs.
src/WireMock.Net.Abstractions/Types/WireMockList.cs Adds operators and value-based equality/hash code implementation.
src/WireMock.Net.Abstractions/Models/IBodyData.cs Updates BodyAsFormUrlEncoded type to WireMockList<string> values.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

@Bafyn Bafyn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some comments from copilot also make sense like unused vars, etc.

StefH and others added 2 commits August 19, 2026 19:15
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@StefH StefH changed the title Fix FormurlMatcher logic (+ refactor values / matchers logic) Fix FormUrlEncodedMatcher (+ refactor values / matchers logic) Aug 19, 2026
@StefH
StefH merged commit ee0f890 into master Aug 20, 2026
13 of 15 checks passed
@StefH
StefH deleted the formurl_match branch August 20, 2026 15:31
neotrow pushed a commit to neolution-ch/Csag.Blueprint that referenced this pull request Oct 29, 2026
Updated
[coverlet.collector](https://github.com/coverlet-coverage/coverlet) from
10.0.1 to 10.1.0.

<details>
<summary>Release notes</summary>

_Sourced from [coverlet.collector's
releases](https://github.com/coverlet-coverage/coverlet/releases)._

## 10.1.0

### Improvements

- Publish Microsoft.Testing.Platform coverage messages from coverlet.MTP
[#​2019](coverlet-coverage/coverlet#2019)
- Implement dynamic exclusion filters for assemblies (Coverlet.MTP)
[#​1946](coverlet-coverage/coverlet#1946)
- Replace legacy .sln files with modern .slnx format
[#​1966](coverlet-coverage/coverlet#1966)
- coverlet.console: add trace diagnostics and actionable warnings for
instrumentation/hit/empty-result failures
[#​2005](coverlet-coverage/coverlet#2005)
- Relax auto-property skip logic and improve coverage for records
[#​1941](coverlet-coverage/coverlet#1941)

### Fixed

- Fix coverlet.MTP does not collect coverage on the .NET Framework
portion of a large project
[#​1980](coverlet-coverage/coverlet#1980)
[#​1967](coverlet-coverage/coverlet#1967)
- Fix Regression in branch coverage for lambda expressions
[#​1938](coverlet-coverage/coverlet#1938)
- Fix When using "is" with "or" in pattern matching, branch coverage is
lower than normal
[#​1979](coverlet-coverage/coverlet#1979)
- Fix silent zero coverage on .NET Framework since 8.0.0
[#​1985](coverlet-coverage/coverlet#1985) by
@​tobiwae
- Fix Race condition between ProcessExit hit-file write and out-of-proc
coverage read causes EndOfStreamException
[#​1987](coverlet-coverage/coverlet#1987)
[#​1988](coverlet-coverage/coverlet#1988) by
@​bkoelman
- Fix Regression TypeInitializationException when targeting .NET
Framework - Could not load type
'System.Collections.Concurrent.ConcurrentBag
[#​2010](coverlet-coverage/coverlet#2010)
- Fix use --config-file CLI arg in coverlet.MTP
[#​2030](coverlet-coverage/coverlet#2030) by
alexthornton1
- Fix silently empty coverage for shared-framework assemblies missing
from compileLibraries
[#​2032](coverlet-coverage/coverlet#2032) by
@​Eljees

[Diff between 10.0.1 and
10.1.0](coverlet-coverage/coverlet@v10.0.1...v10.1.0)

Commits viewable in [compare
view](coverlet-coverage/coverlet@v10.0.1...v10.1.0).
</details>

Updated
[FluentValidation](https://github.com/JeremySkinner/fluentvalidation)
from 12.1.1 to 12.2.0.

<details>
<summary>Release notes</summary>

_Sourced from [FluentValidation's
releases](https://github.com/JeremySkinner/fluentvalidation/releases)._

## 12.2.0

# Release notes

[Please read the upgrade guide if you are moving from 11.x to
12.x](https://docs.fluentvalidation.net/en/latest/upgrading-to-12.html)

## Changes in 12.2.0

- Add Lithuanian language (#​2350)
- Add Belarusian language (#​2356)
- Add GetParentChain() to PropertyChain (#​2358)
- Fix ArgumentNullException in TestValidationResult when a failure has a
null PropertyName (#​2362)
- Reject an inverted range when the comparer returns a negative other
than -1 in RangeValidator (#​2370)
- Change EnumValidator to work under native AOT (#​2371)
- Fix PropertyChain.IsChildChainOf for sibling chains that share a name
prefix (#​2372)
- Fix PropertyPath is incorrect in .When() on RuleForEach (#​2363)

## Changes in 12.1.0 
- Add Tamil language (#​2334)
- Add Telugu language (#​2333)
- Fixes to Japanese translations (#​2340)

## Changes in 12.0.0 

- Drops support for netstandard2.0, netstandard2.1, .net 5, .net 6 and
.net 7. Minimum supported platform is now .net 8.
- Add support for dependent rules for custom rules (#​2170)
- Removes deprecated DI extensions
- Removes deprecated transform methods (#​2027)
- Remove the ability to disable the root-model null check (#​2069)
- Use Zomp.SyncMethodGenerator to clean up internal sync/async code
paths and increase performance (#​2136)
- Add Serbian (Cyrillic) language; rename existing Serbian to Serbian
(Latin) (#​2283)

# Downloads

Binaries can be downloaded from nuget:
- [FluentValidation](http://nuget.org/packages/fluentvalidation) - Main
package


Commits viewable in [compare
view](https://github.com/JeremySkinner/fluentvalidation/commits/12.2.0).
</details>

Updated [Microsoft.Data.SqlClient](https://github.com/dotnet/sqlclient)
from 7.0.3 to 7.1.1.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.Data.SqlClient's
releases](https://github.com/dotnet/sqlclient/releases)._

## 7.1.1

This servicing release fixes decimal parameter validation, token expiry
handling in connection pool V2, and connection opens that are in
progress when a pool is cleared.

> **Package version alignment:** The SqlClient family packages share the
`7.1.1` version:
>
> - `Microsoft.Data.SqlClient`
> - `Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider`
> - `Microsoft.Data.SqlClient.Extensions.Azure`
> - `Microsoft.Data.SqlClient.Extensions.Abstractions`
> - `Microsoft.Data.SqlClient.Internal.Logging`
>
> `Microsoft.SqlServer.Server` is versioned independently and is not
part of this release. Applications should use matching `7.1.1` versions
of the driver and its companion packages. The aligned assemblies retain
`AssemblyVersion 7.0.0.0`; upgrading from `7.1.0` does not require new
.NET Framework strong-name binding redirects.

### Companion package release notes

- [Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
7.1.1](https://github.com/dotnet/SqlClient/blob/main/release-notes/add-ons/AzureKeyVaultProvider/7.1/7.1.1.md)
- [Microsoft.Data.SqlClient.Extensions.Azure
7.1.1](https://github.com/dotnet/SqlClient/blob/main/release-notes/Extensions/Azure/7.1/7.1.1.md)
- [Microsoft.Data.SqlClient.Extensions.Abstractions
7.1.1](https://github.com/dotnet/SqlClient/blob/main/release-notes/Extensions/Abstractions/7.1/7.1.1.md)
- [Microsoft.Data.SqlClient.Internal.Logging
7.1.1](https://github.com/dotnet/SqlClient/blob/main/release-notes/Internal/Logging/7.1/7.1.1.md)

## Changes Since
[7.1.0](https://github.com/dotnet/SqlClient/blob/main/release-notes/7.1/7.1.0.md)

### Fixed

- Fixed an `ArgumentException` when sending zero-valued `decimal` or
`SqlDecimal` parameters whose precision equals their scale. Nonzero
precision validation and support for large decimal values are unchanged.
([#​4715](dotnet/SqlClient#4715),
[#​4721](dotnet/SqlClient#4721),
[#​4732](dotnet/SqlClient#4732))

- Fixed connection pool V2 handing out pooled connections with expired
or nearly expired access tokens. The pool now checks token expiry before
reuse, matching the default pool's behavior while preserving
transaction-affine reuse. This affects only applications that opt in to
connection pool V2.
([#​4734](dotnet/SqlClient#4734),
[#​4739](dotnet/SqlClient#4739))

- Fixed connection opens failing when `ClearPool` or `ClearAllPools`
races with an in-flight open. Requests already admitted to the cleared
pool can finish, and connections returned to the retired pool are
discarded rather than reused.
([#​4714](dotnet/SqlClient#4714),
[#​4718](dotnet/SqlClient#4718),
[#​4740](dotnet/SqlClient#4740))

## Target Platform Support

- .NET Framework 4.6.2+ (Windows x86, Windows x64, Windows ARM64)
- .NET 8.0+ (Windows x86, Windows x64, Windows ARM, Windows ARM64,
Linux, macOS)

### Dependencies

#### .NET 9.0

- Microsoft.Bcl.Cryptography 9.0.18
- Microsoft.Data.SqlClient.Extensions.Abstractions 7.1.1
- Microsoft.Data.SqlClient.Internal.Logging 7.1.1
- Microsoft.Data.SqlClient.SNI.runtime 7.1.0
- Microsoft.Extensions.Caching.Memory 9.0.18
- Microsoft.IdentityModel.JsonWebTokens 8.16.0
- Microsoft.IdentityModel.Protocols.OpenIdConnect 8.16.0
- Microsoft.SqlServer.Server 1.0.0
- System.Configuration.ConfigurationManager 9.0.18
- System.Security.Cryptography.Pkcs 9.0.18
- System.Threading.RateLimiting 9.0.18

 ... (truncated)

## 7.1.0

This is the general availability release of **Microsoft.Data.SqlClient
7.1**. It closes out the `7.1` preview cycle with application identity
reporting for telemetry, the deprecation of
`TransparentNetworkIPResolution`, and a set of connection, transaction,
and Named Pipes fixes.

> **Important — package version alignment:** Starting with the
[7.0.2](https://github.com/dotnet/SqlClient/blob/main/release-notes/7.0/7.0.2.md)
release, the `Microsoft.Data.SqlClient` driver and its companion
packages share a single aligned version. The `7.1.0` GA release
continues this alignment; the following packages ship together as
`7.1.0`:
>
> - `Microsoft.Data.SqlClient`
> - `Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider`
> - `Microsoft.Data.SqlClient.Extensions.Azure`
> - `Microsoft.Data.SqlClient.Extensions.Abstractions`
> - `Microsoft.Data.SqlClient.Internal.Logging`
>
> (`Microsoft.SqlServer.Server` continues to version independently and
remains at `1.0.0`.)
>
> Applications must reference the same versions of
`Microsoft.Data.SqlClient` and its extensions for best compatibility. In
particular, applications that reference
`Microsoft.Data.SqlClient.Extensions.Azure` must upgrade it to `7.1.0`
when upgrading `Microsoft.Data.SqlClient` to `7.1.0`.
>
> **Compatibility guarantee:** All aligned assemblies ship with
`FileVersion 7.1.0.x` and `AssemblyVersion 7.0.0.0`. The
`AssemblyVersion` is unchanged from
[7.0.2](https://github.com/dotnet/SqlClient/blob/main/release-notes/7.0/7.0.2.md),
so upgrading from `7.0.2`, `7.0.3`, or any `7.1` preview to `7.1.0` does
**not** require any new .NET Framework strong-name binding redirects.
Applications upgrading from `7.0.0` or `7.0.1` should note that
`Extensions.Azure`, `Extensions.Abstractions`, and `Internal.Logging`
raised their `AssemblyVersion` from `1.0.0.0` to `7.0.0.0` in
[7.0.2](https://github.com/dotnet/SqlClient/blob/main/release-notes/7.0/7.0.2.md);
see those release notes for the one-time .NET Framework impact.

### Companion package release notes

- [Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
7.1.0](https://github.com/dotnet/SqlClient/blob/main/release-notes/add-ons/AzureKeyVaultProvider/7.1/7.1.0.md)
- [Microsoft.Data.SqlClient.Extensions.Azure
7.1.0](https://github.com/dotnet/SqlClient/blob/main/release-notes/Extensions/Azure/7.1/7.1.0.md)
- [Microsoft.Data.SqlClient.Extensions.Abstractions
7.1.0](https://github.com/dotnet/SqlClient/blob/main/release-notes/Extensions/Abstractions/7.1/7.1.0.md)
- [Microsoft.Data.SqlClient.Internal.Logging
7.1.0](https://github.com/dotnet/SqlClient/blob/main/release-notes/Internal/Logging/7.1/7.1.0.md)

## Changes Since
[7.1.0-preview3](https://github.com/dotnet/SqlClient/blob/main/release-notes/7.1/7.1.0-preview3.md)

### Added

#### Application Identity in the USERAGENT Payload

*What Changed:*

- Added a `RegisteredApplication` enum and a matching
`SqlConnection.RegisteredApplication` property that let a library or
tool identify itself to SQL Server through version 2 of the TDS
USERAGENT feature extension. The payload also carries a new driver-owned
64-bit *Driver Properties* flag field; bit 0 reports whether connection
pool V2 is enabled for the process. Both fields are emitted as unpadded
uppercase hexadecimal.
([#​3201](dotnet/SqlClient#3201),
[#​4632](dotnet/SqlClient#4632))

*Who Benefits:*

- Middleware and tooling built on top of the driver — Entity Framework
Core, Semantic Kernel, SQL Server Management Studio, SqlPackage, Data
API Builder, and similar — can be distinguished in server-side telemetry
without the driver accepting arbitrary user-supplied user-agent text.
This originated as a request from the Entity Framework Core team.
- Service operators gain a more accurate picture of which client stacks
are connecting, which helps when diagnosing workload-specific behavior.

*Impact:*

- Purely additive from the application's perspective: a newly created
physical connection whose `RegisteredApplication` is unset reports
`Unknown` (`0`). On the wire the field itself is new — USERAGENT payload
v1 carried no application identifier, while v2 always emits one.
- Set the property before calling `Open` or `OpenAsync`. Assigning it
while the connection is connecting or open throws
`InvalidOperationException`.

```c#
using var connection = new SqlConnection(connectionString);
connection.RegisteredApplication = RegisteredApplication.EntityFrameworkCore;
await connection.OpenAsync();
```

- The enum is `ushort`-backed and marked `[CLSCompliant(false)]`. Values
are partitioned by range: `0x0001`–`0x7FFF` for Microsoft-defined
large-scale applications, `0x8000`–`0xBFFF` for small-scale use, and
`0xC000`–`0xFFFF` for public/developer use. Applications that are not
yet registered can cast an unassigned value from the appropriate range.
 ... (truncated)

## 7.1.0-preview3

This update brings the following changes since the
[7.1.0-preview2](https://github.com/dotnet/SqlClient/blob/main/release-notes/7.1/7.1.0-preview2.md)
release.

> **Package version alignment:** The `Microsoft.Data.SqlClient` driver
and its companion packages continue the aligned versioning introduced in
[7.0.2](https://github.com/dotnet/SqlClient/blob/main/release-notes/7.0/7.0.2.md).
All five packages listed below ship together as `7.1.0-preview3`.
(`Microsoft.SqlServer.Server` continues to version independently and
remains at `1.0.0`.) Applications that reference
`Microsoft.Data.SqlClient.Extensions.Azure` must upgrade it to
`7.1.0-preview3` when upgrading `Microsoft.Data.SqlClient`.

> **Compatibility guarantee:** All aligned assemblies ship with
`FileVersion 7.1.0.x` and `AssemblyVersion 7.0.0.0` — unchanged from
7.0.2 — so upgrading from `7.0.2` to `7.1.0-preview3` does **not**
require any new .NET Framework strong-name binding redirects.

## Packages in this release

### `Microsoft.Data.SqlClient` 7.1.0-preview3

**Added**
- Asynchronous key store provider APIs for Always Encrypted — four
`virtual` methods on `SqlColumnEncryptionKeyStoreProvider` with
`CancellationToken` support. Purely additive; defaults delegate to the
synchronous methods, so existing providers are unaffected
([#​3672](dotnet/SqlClient#3672),
[#​3673](dotnet/SqlClient#3673))
- Connection Pool V2 nears parity with the default pool (opt-in via
`Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2`):
- Transaction support
([#​4487](dotnet/SqlClient#4487))
- Broken-connection replacement during command execution
([#​4429](dotnet/SqlClient#4429))
- Background warmup to `Min Pool Size` and automatic replenishment
([#​4452](dotnet/SqlClient#4452))
- Idle pruning driven by `Connection Idle Timeout`
([#​4463](dotnet/SqlClient#4463))
- Optional `ConcurrencyLimiter` rate limiting for new physical
connections ([#​4395](dotnet/SqlClient#4395),
[#​4396](dotnet/SqlClient#4396))
- Leaked connection reclamation, including the previously always-zero
`number-of-reclaimed-connections` counter
([#​4529](dotnet/SqlClient#4529))
- Metrics and tracing parity with the default pool
([#​4504](dotnet/SqlClient#4504))

**Changed**
- Single cross-platform build — Windows-only native SNI types now trim
cleanly on Linux and macOS. Package structure and contents unchanged
([#​4207](dotnet/SqlClient#4207),
[#​4239](dotnet/SqlClient#4239),
[#​4465](dotnet/SqlClient#4465),
[#​4474](dotnet/SqlClient#4474))
- Async read-path allocations restored to baseline via `PacketData` node
reuse — `ExecuteReaderAsync` goes from +120.9% to +0.1% against 6.1.6
([#​4536](dotnet/SqlClient#4536))
- `SqlBulkCopy` skips graph alias mapping when no graph pseudo-columns
are present, recovering a regression from
[#​3677](dotnet/SqlClient#3677)
([#​4535](dotnet/SqlClient#4535))
- No formatted trace string is allocated when `SqlClientEventSource`
tracing is disabled, recovering a memory regression against 6.1.6. Trace
output unchanged
([#​4528](dotnet/SqlClient#4528))
- `net9.0` dependencies moved to `9.0.18`;
`System.Threading.RateLimiting` added to packaged metadata. Other
targets keep their `8.0.x` pins
([#​4507](dotnet/SqlClient#4507))
- `Microsoft.Data.SqlClient.SNI` and `.SNI.runtime` updated to
`7.1.0-preview3.26226.3`
([#​4564](dotnet/SqlClient#4564))

**Fixed**
- Always Encrypted VSM/HGS attestation now verifies the enclave public
key is bound to the signed report, using a fixed-time `SHA-256`
comparison against `EnclaveData`
([#​4532](dotnet/SqlClient#4532))
- `SqlConnectionFactory` no longer wakes the process every 30 seconds
when no pools exist — including with `Pooling=False` and after
`ClearAllPools()`
([#​1881](dotnet/SqlClient#1881),
[#​4479](dotnet/SqlClient#4479))
- Connection pool performance counters affecting the **default** pool as
well as pool V2 — `active-soft-connects` and
`number-of-active-connections` could go negative after a failed
activation, and several gauges drifted upward permanently after a broken
connection was replaced
([#​4504](dotnet/SqlClient#4504))
- `OverflowException` when sending large `decimal` values with explicit
`Precision` and `Scale`, which primarily affected Always Encrypted
([#​1655](dotnet/SqlClient#1655),
[#​4443](dotnet/SqlClient#4443))
- TDS stream error when passing a `DateOnly` value with
`SqlDbType.Variant` (net8.0/net9.0)
([#​3953](dotnet/SqlClient#3953),
[#​4294](dotnet/SqlClient#4294))
- `DateOnly` in table-valued parameter `sql_variant` columns sent as
`datetime` instead of `date`, which overflowed for values valid as
`date` (net8.0/net9.0)
([#​3934](dotnet/SqlClient#3934),
[#​4439](dotnet/SqlClient#4439))
- `ServerCertificate` keyword ignored when the platform reported no TLS
policy errors. It is now always compared, and an unloadable certificate
fails closed with `SSLCertificateAuthenticationException` instead of
silently falling back to host-name validation
([#​4445](dotnet/SqlClient#4445))
- `SqlConnection.AccessTokenCallback` not disabling TNIR by default,
plus pool-key construction and `SspiContextProvider` exclusivity with
token auth (net462 for the TNIR behavior)
([#​4520](dotnet/SqlClient#4520))
- Fatal exceptions such as `OutOfMemoryException` captured into faulted
`Task`s across several `SqlBulkCopy`, `SqlDataReader`, and `SqlCommand`
async entry points
([#​4437](dotnet/SqlClient#4437))
- Entra ID authentication failing against multi-segment authorities such
as the Dataverse / Dynamics 365 TDS endpoint. Ships in
`Microsoft.Data.SqlClient.Extensions.Azure`
([#​4496](dotnet/SqlClient#4496),
[#​4521](dotnet/SqlClient#4521))

Full details:
[release-notes/7.1/7.1.0-preview3.md](https://github.com/dotnet/SqlClient/blob/main/release-notes/7.1/7.1.0-preview3.md)

---

### `Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider`
7.1.0-preview3

**Added**
- `SqlColumnEncryptionAzureKeyVaultProvider` overrides the four
asynchronous key store provider methods introduced in
[#​3673](dotnet/SqlClient#3673), calling the
Azure SDK's own async APIs and flowing the supplied `CancellationToken`
([#​4540](dotnet/SqlClient#4540))
- Concurrent cache misses for the same key collapse into a single Key
Vault request. The gate is only awaited, so no thread blocks, and misses
for different keys still proceed in parallel
([#​4540](dotnet/SqlClient#4540))
 ... (truncated)

## 7.1.0-preview2

This update brings the following changes since the
[7.1.0-preview1](https://github.com/dotnet/SqlClient/blob/main/release-notes/7.1/7.1.0-preview1.md)
release.

> **Package version alignment:** The `Microsoft.Data.SqlClient` driver
and its companion packages continue the aligned versioning introduced in
[7.0.2](https://github.com/dotnet/SqlClient/blob/main/release-notes/7.0/7.0.2.md).
All five packages listed below ship together as `7.1.0-preview2`.
(`Microsoft.SqlServer.Server` continues to version independently and
remains at `1.0.0`.) Applications that reference
`Microsoft.Data.SqlClient.Extensions.Azure` must upgrade it to
`7.1.0-preview2` when upgrading `Microsoft.Data.SqlClient`.

> **Compatibility guarantee:** All aligned assemblies ship with
`FileVersion 7.1.0.x` and `AssemblyVersion 7.0.0.0` — unchanged from
7.0.2 — so upgrading from `7.0.2` to `7.1.0-preview2` does **not**
require any new .NET Framework strong-name binding redirects.

## Packages in this release

### `Microsoft.Data.SqlClient` 7.1.0-preview2

**Added**
- `SqlConnection.GetSchemaAsync` overloads with `CancellationToken`
support ([#​3005](dotnet/SqlClient#3005))
- SQL Graph pseudo-column aliases (`$node_id`, `$edge_id`, `$from_id`,
`$to_id`) accepted in `SqlBulkCopy` mappings
([#​3677](dotnet/SqlClient#3677))
- `SqlBatchCommand.CommandBehavior` and
`SqlBatch.ExecuteReader(CommandBehavior)` are now honored
([#​4125](dotnet/SqlClient#4125))
- Configurable idle connection timeout via `Connection Idle Timeout` /
`SqlConnectionStringBuilder.IdleTimeout` (opt-in via
`Switch.Microsoft.Data.SqlClient.UseLegacyIdleTimeoutBehavior=false`)
([#​4295](dotnet/SqlClient#4295))

**Changed**
- `Connect Timeout` now propagates through the pool when
`Switch.Microsoft.Data.SqlClient.UseOverallConnectTimeoutForPoolWait=true`
is set (default off; introduces a `Microsoft.Bcl.TimeProvider`
dependency) ([#​4270](dotnet/SqlClient#4270))
- SQL Server 2025 `json` type added to the `DataTypes` collection
returned by `SqlConnection.GetSchema`
([#​3858](dotnet/SqlClient#3858))
- Internal state-machine hardening via `Interlocked.CompareExchange`
guards ([#​4267](dotnet/SqlClient#4267))
- Internal cleanup of connection-options inheritance and related pool
interfaces ([#​4237](dotnet/SqlClient#4237),
[#​4261](dotnet/SqlClient#4261),
[#​4235](dotnet/SqlClient#4235),
[#​4415](dotnet/SqlClient#4415),
[#​4334](dotnet/SqlClient#4334))
- LCID hardcoded mappings to avoid repeated culture lookups
([#​4212](dotnet/SqlClient#4212))
- Allocation reductions on `SqlErrorCollection` and null-return paths
([#​4157](dotnet/SqlClient#4157),
[#​4099](dotnet/SqlClient#4099),
[#​4102](dotnet/SqlClient#4102))
- Improved `EnclaveDiffieHellmanInfo.Size` accuracy
([#​4346](dotnet/SqlClient#4346))
- `SqlVector<float>` serialization is now explicitly little-endian for
cross-architecture consistency
([#​3861](dotnet/SqlClient#3861))
- Bundled .NET 10 SDK updated to `10.0.300`
([#​4287](dotnet/SqlClient#4287))

**Fixed**
- `NullReferenceException` in `SqlCommand.Cancel()` when the connection
has already been torn down
([#​4372](dotnet/SqlClient#4372))
- Always Encrypted CMK signature verification incorrectly reusing cached
results after a prior failure
([#​4339](dotnet/SqlClient#4339))
- Missing TDS token / feature-ack length bounds checks (spoofing server
could trigger unbounded allocations)
([#​4340](dotnet/SqlClient#4340))
- `SqlBulkCopy` failing in least-privilege environments
([#​4306](dotnet/SqlClient#4306))
- Always Encrypted `CekMdVersion` / `EkValueCount` reads aligned with
the TDS specification
([#​4240](dotnet/SqlClient#4240))
- `LoginWithFailover` parser-state validation
([#​4140](dotnet/SqlClient#4140))
- SPN during login now uses the resolved port instead of instance name
for `Protocol=None` / `Protocol=Admin`
([#​4180](dotnet/SqlClient#4180))
- Race in `SqlConnection.TryOpenInner` that could surface as
`InvalidCastException` now returns a deterministic
`InvalidOperationException`
([#​4179](dotnet/SqlClient#4179))
- Multiple `CancellationTokenSource` leaks in `SqlDataReader`,
`SqlConnection`, `SqlCommand` reconnect paths, and sequential-stream
helpers ([#​4009](dotnet/SqlClient#4009))
- Docs fix for server certificate configuration
([#​4408](dotnet/SqlClient#4408))

**Removed (breaking)**
- SQL Server 7.0 / 2000 code paths removed; `Type System Version=SQL
Server 2000` now throws `ArgumentException` at open. Applications should
switch to `Latest` (or another supported value). No change to
server-version support — 7.0 / 2000 were already rejected during login
version negotiation.
([#​4015](dotnet/SqlClient#4015))

Full details:
[release-notes/7.1/7.1.0-preview2.md](https://github.com/dotnet/SqlClient/blob/main/release-notes/7.1/7.1.0-preview2.md)

---

### `Microsoft.Data.SqlClient.Extensions.Azure` 7.1.0-preview2

**Added — WAM (Windows Account Manager) broker support for Entra ID
authentication (Windows only)**
([#​4288](dotnet/SqlClient#4288),
[#​4388](dotnet/SqlClient#4388))
- Covers `ActiveDirectoryIntegrated`, `ActiveDirectoryInteractive`,
`ActiveDirectoryDeviceCodeFlow`, and the deprecated
`ActiveDirectoryPassword` modes.
 ... (truncated)

## 7.1.0-preview1

This update brings the following changes since the
[7.0.0](https://github.com/dotnet/SqlClient/blob/main/release-notes/7.0/7.0.0.md)
release:

### Added

#### `SqlBatch` Support on .NET Framework

*What Changed:*

- Added `SqlBatch` and related batch-command support for the .NET
Framework target so the batching API is now available across the full
supported platform matrix, including `net462`.
([#​3926](dotnet/SqlClient#3926))

*Who Benefits:*

- Applications that target .NET Framework but also want to use the newer
batching APIs no longer need a separate implementation strategy from
.NET 8/9 applications.
- Libraries that multi-target .NET Framework and modern .NET can use a
more consistent data-access surface area.

*Impact:*

- `SqlBatch`, `SqlBatchCommand`, and the related execution methods are
now usable on .NET Framework builds in addition to .NET.

#### Cross-Driver Connection-String Synonym Alignment

*What Changed:*

- Added additional accepted connection-string synonyms for better
compatibility with other SQL Server drivers and existing
connection-string conventions. Newly accepted synonyms include
`ColumnEncryption`, `ConnectTimeout`, `FailoverPartner`, `PacketSize`,
and `WorkstationId`.
([#​4192](dotnet/SqlClient#4192))

*Who Benefits:*

- Applications migrating connection strings from other SQL Server
drivers or shared infrastructure can reuse more existing keywords
without rewriting them first.

*Impact:*

- Existing canonical keywords continue to work unchanged; this preview
simply accepts more equivalent aliases during parsing.

### Changed
#### Type Forwards for Authentication Abstractions

*What Changed:*

- Added type forwards from the core `Microsoft.Data.SqlClient` assembly
to public authentication-related types that were moved into
`Microsoft.Data.SqlClient.Extensions.Abstractions`, including
`SqlAuthenticationMethod`, `SqlAuthenticationParameters`,
`SqlAuthenticationProvider`, `SqlAuthenticationProviderException`, and
`SqlAuthenticationToken`.
([#​4067](dotnet/SqlClient#4067),
[#​4117](dotnet/SqlClient#4117))

*Who Benefits:*

- Applications and libraries compiled against earlier package layouts
retain binary compatibility when those authentication types are resolved
from the core assembly name.

*Impact:*

- No application code changes are required; the type forwards preserve
existing compiled references.

#### User Agent Feature Extension Enabled by Default

 ... (truncated)

Commits viewable in [compare
view](dotnet/SqlClient@v7.0.3...v7.1.1).
</details>

Updated
[Microsoft.Extensions.TimeProvider.Testing](https://github.com/dotnet/extensions)
from 10.10.0 to 10.11.0.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.Extensions.TimeProvider.Testing's
releases](https://github.com/dotnet/extensions/releases)._

## 10.11.0

# .NET Extensions 10.11.0

This release adds optional scope capture for buffered logs and updates
experimental HTTP latency enrichment APIs. It also includes fixes for AI
streaming and function invocation, evaluation reports, HybridCache
invalidation, and logging.

## Experimental API Changes

### New Experimental APIs

* Optional logging-scope capture for global and per-request log
buffering through `GlobalLogBufferingOptions.IncludeScopes` and
`PerRequestLogBufferingOptions.IncludeScopes` (`EXTEXP0003`) #​7813

### Breaking Changes to Experimental APIs

* Incoming HTTP latency log enrichment: `AddHttpLatencyTelemetry` is
renamed to `AddHttpServerLatencyTelemetry` and moves from
`HttpLatencyTelemetryServiceCollectionExtensions` to
`HttpLoggingServiceCollectionExtensions`. It remains experimental under
`EXTEXP0013` in this release. #​7730

## What's Changed

### AI

* Yield final image when streaming with HostedImageGenerationTool #​7774
by @​iamAdarshh
* Make the default tool-rejection message state that the decision is
final #​7784 by @​manjunathshiva
* AI: Remove obsolete OpenAI JsonPatch workaround #​7815 by @​jozkee
(co-authored by @​Copilot)
* Ignore empty model IDs in streaming responses #​7816 by @​valkiara
* Honor FunctionInvocationContext.Terminate when the function throws
#​7801 by @​gjz22
* Fix ChatResponseUpdate.Clone dropping ContinuationToken #​7699 by
@​dfedoryshchev
* Decode non-base64 data URIs in DataContent to the octets they encode
#​7798 by @​Laurianti

### AI Evaluation

* [M.E.AI.Evaluation.Reporting] Fix context and metric interpretation
visualization #​7738 by @​grafanaKibana
* Fix tokenizer attaching punctuation to number tokens #​7766 by
@​tahakocal
* Order iteration results numerically #​7769 by @​tahakocal
* Score GLEU against the best matching reference #​7768 by @​tahakocal

### Telemetry and Observability

* Optionally preserve logging scopes in buffered log records #​7813 by
@​evgenyfedorov2 (co-authored by @​Copilot)
* Fix OOM from unbounded enumeration of ExtendedLogger tag joiners
#​7819 by @​evgenyfedorov2 (co-authored by @​Copilot)
* Fix log buffering race by removing the rule selector cache #​7803 by
@​evgenyfedorov2 (co-authored by @​Copilot)

### ASP.NET Core Extensions

* Rename AddHttpLatencyTelemetry to AddHttpServerLatencyTelemetry
(API-approved shape) #​7730 by @​EasyL0ver (co-authored by @​Copilot)
* Fix ArgumentNullException in per-request log buffering at the end of a
request #​7811 by @​evgenyfedorov2 (co-authored by @​Copilot)

### AI Project Templates

* Align aichatweb local vector-store keys with Guid record keys #​7804
by @​jongalloway (co-authored by @​adamsitnik @​Copilot)

### Caching

 ... (truncated)

## 10.10.1

This release fixes two OpenAI integration issues: a TypeLoadException on
tool-carrying Responses API calls and a streaming crash against
third-party OpenAI-compatible endpoints, by upgrading the OpenAI SDK to
2.14.0.

## Packages in this release

| Package | Version |
|---------|---------|
| Microsoft.Extensions.AI.OpenAI | `10.10.1` |
| Microsoft.Extensions.AI.Abstractions | `10.10.1` |

## What's Changed

### AI

* Upgrade OpenAI SDK to 2.14.0 #​7761 by @​zxyao145

## Acknowledgements

* @​zxyao145 made their first contribution in #​7761
* @​zxyao145 submitted issue #​7760 (resolved by #​7761)
* @​jozkee @​wtgodbe reviewed pull requests

**Full Changelog**:
dotnet/extensions@v10.10.0...v10.10.1


Commits viewable in [compare
view](dotnet/extensions@v10.10.0...v10.11.0).
</details>

Updated [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest)
from 18.10.1 to 18.11.0.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.NET.Test.Sdk's
releases](https://github.com/microsoft/vstest/releases)._

## 18.11.0

<!-- Release notes generated using configuration in .github/release.yml
at rel/18.11 -->

## What's Changed
* Fix TRX logger mangling astral-plane (non-BMP) characters by
@​azat-msft in microsoft/vstest#16318
* Disable the MTP testhost by default by @​nohwnd in
microsoft/vstest#16337
* Fix OS-blind apphost probe in MTP bridge on Unix (regression from
#​16201) by @​azat-msft in
microsoft/vstest#16336
* Retarget the MTP client onto
Microsoft.Testing.Platform.ServerMode.Client.Sources by @​nohwnd in
microsoft/vstest#16300
* Pass arguments to PowerShell with -File instead of -command by
@​nohwnd in microsoft/vstest#16363
* Respect console logger verbosity from a settings file by @​nohwnd in
microsoft/vstest#16044
* Fix backslash normalization in VSTestCLIRunSettings on Unix by
@​nohwnd in microsoft/vstest#15795
* Docs: fix typo explicitely -> explicitly by @​vaibhav8a in
microsoft/vstest#16397
* Copy acceptance test diagnostic logs into the test results directory
by @​nohwnd in microsoft/vstest#16403

## New Contributors
* @​vaibhav8a made their first contribution in
microsoft/vstest#16397

**Full Changelog**:
microsoft/vstest@v18.10.1...v18.11.0

Commits viewable in [compare
view](microsoft/vstest@v18.10.1...v18.11.0).
</details>

Updated
[Testcontainers.MsSql](https://github.com/testcontainers/testcontainers-dotnet)
from 4.15.0 to 4.16.0.

<details>
<summary>Release notes</summary>

_Sourced from [Testcontainers.MsSql's
releases](https://github.com/testcontainers/testcontainers-dotnet/releases)._

## 4.16.0

# What's Changed

Huge thanks to everyone for your contributions and feedback 🧡.

The NuGet packages for this release have been attested for supply chain
security using [`actions/attest`](https://github.com/actions/attest).
This confirms the integrity and provenance of the artifacts and helps
ensure they can be trusted:
[#​54051351](https://github.com/testcontainers/testcontainers-dotnet/attestations/54051351).

## 🚀 Features

* feat: Add common WithSsl builder API and support it in Azurite
(#​1788) @​aleksandarMilev, @​HofmeisterAn
* feat: Add BuildKit support for image builds via sidecar container
(#​1761) @​george-petrakis, @​HofmeisterAn
* feat(Elasticsearch): Add OTLP and certificate support (#​1774)
@​HofmeisterAn

## 🐛 Bug Fixes

* fix(PostgreSql): Support SSL with Alpine images and non-root users
(#​1790) @​HofmeisterAn
* fix: Do not pull base image with unresolved platform variable (#​1787)
@​HofmeisterAn
* fix(Kafka): Default to KRaft for Confluent Platform 8.x images
(#​1775) @​arnelirobles, @​HofmeisterAn
* fix(Kafka): Drop the trailing comma from advertised listeners (#​1772)
@​arnelirobles, @​HofmeisterAn
* fix: Prevent Docker ignore patterns from matching path prefixes
(#​1768) @​Benziza, @​HofmeisterAn

## 📖 Documentation

* docs: Complete builder API tables and align heading casing (#​1778)
@​HofmeisterAn
* docs: Explain how builder configurations combine (#​1770)
@​arnelirobles, @​HofmeisterAn

## 🧹 Housekeeping

* fix: Regenerate expired test certificates (#​1786) @​zcsizmadia
* chore: Resolve Sonar findings (#​1776) @​HofmeisterAn
* chore: Remove Minio module (#​1769) @​HofmeisterAn
* chore: Publish NuGet packages with Trusted Publishing (OIDC) (#​1763)
@​HofmeisterAn
* feat: Prepare next release cycle (4.16.0) (#​1762) @​HofmeisterAn

## 📦 Dependency Updates

* chore(deps): Bump the actions group with 5 updates (#​1781)
[@​dependabot[bot]](https://github.com/apps/dependabot)


Commits viewable in [compare
view](testcontainers/testcontainers-dotnet@4.15.0...4.16.0).
</details>

Updated
[WireMock.Net.Testcontainers](https://github.com/wiremock/WireMock.Net)
from 2.15.0 to 2.19.0.

<details>
<summary>Release notes</summary>

_Sourced from [WireMock.Net.Testcontainers's
releases](https://github.com/wiremock/WireMock.Net/releases)._

## 2.19.0

## What's Changed
* Add example /test by @​StefH in
wiremock/WireMock.Net#1513
* Use IDateTimeUtils in WireMockWebSocketContext by @​StefH in
wiremock/WireMock.Net#1512
* Fix DateTime in Response by @​StefH in
wiremock/WireMock.Net#1514


**Full Changelog**:
wiremock/WireMock.Net@2.18.0...2.19.0

## 2.18.0

## What's Changed
* WireMock.Net.OpenApiParser: fix depencency on
RamlToOpenApiConverter.SourceOnly by @​StefH in
wiremock/WireMock.Net#1510


**Full Changelog**:
wiremock/WireMock.Net@2.17.0...2.18.0

## 2.17.0

## What's Changed
* Revert to RamlToOpenApiConverter.SourceOnly by @​StefH in
wiremock/WireMock.Net#1509


**Full Changelog**:
wiremock/WireMock.Net@2.16.0...2.17.0

## 2.16.0

## What's Changed
* Fix #​1501: Generate WhenStateIs/WillSetStateTo correctly in
ToCSharpCode by @​Bafyn in
wiremock/WireMock.Net#1502
* Fix FormUrlEncodedMatcher (+ refactor values / matchers logic) by
@​StefH in wiremock/WireMock.Net#1503
* Update SharpYaml package to version 2.5.1 by @​johnthcall in
wiremock/WireMock.Net#1504
* Upgrade dependency RamlToOpenApiConverter to version 0.40.0 by @​StefH
in wiremock/WireMock.Net#1505


**Full Changelog**:
wiremock/WireMock.Net@2.15.0...2.16.0

Commits viewable in [compare
view](wiremock/WireMock.Net@2.15.0...2.19.0).
</details>

Updated
[xunit.runner.visualstudio](https://github.com/xunit/visualstudio.xunit)
from 4.0.0 to 4.0.1.

<details>
<summary>Release notes</summary>

_Sourced from [xunit.runner.visualstudio's
releases](https://github.com/xunit/visualstudio.xunit/releases)._

## 4.0.1

Release notes: https://xunit.net/releases/visualstudio/4.0.1

Commits viewable in [compare
view](xunit/visualstudio.xunit@4.0.0...4.0.1).
</details>

Updated [xunit.v3.mtp-off](https://github.com/xunit/xunit) from 4.0.1 to
4.0.2.

<details>
<summary>Release notes</summary>

_Sourced from [xunit.v3.mtp-off's
releases](https://github.com/xunit/xunit/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/xunit/xunit/commits).
</details>

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants